<?php

namespace app\command;

use support\Log;
use support\Redis;
use think\facade\Db;
use PhpAmqpLib\Wire\AMQPTable;
use PhpAmqpLib\Message\AMQPMessage;
use PhpAmqpLib\Connection\AMQPStreamConnection;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Output\OutputInterface;
use App\service\order\StoreOrderServices;
use App\service\order\RefundOrderServices;
use App\service\order\BoxOrderServices;


class SelectOrder extends Command
{
    protected static $defaultName = 'select:order';
    protected static $defaultDescription = 'select order';

    /**
     * @return void
     */
    protected function configure()
    {
        $this->addArgument('name', InputArgument::OPTIONAL, 'Name description');
    }

    /**
     * @param InputInterface $input
     * @param OutputInterface $output
     * @return int
     */
    protected function execute(InputInterface $input, OutputInterface $output)
    {
//        $name = $input->getArgument('name');
//        $output->writeln('Hello select:order');

        $v_host = env('RABBITMQ_VHOST');
        $exc_name = 'delay_exc_select_order';
        $routing_key = 'delay_select_order';
        $queue_name = 'delay_queue_select_order';
        $connection = new AMQPStreamConnection('localhost', 5672, env('RABBITMQ_USER'), env('RABBITMQ_PWD'), $v_host);
        $channel = $connection->channel();
        $channel->exchange_declare($exc_name, 'x-delayed-message', false, true, false);
        # 后加
        $args = new AMQPTable(['x-delayed-type' => 'direct']);
        $channel->queue_declare($queue_name, false, true, false, false, false, $args);

        $channel->queue_bind($queue_name, $exc_name, $routing_key);

        $callback = function ($msg) use ($output) {
            //$output->writeln($msg->body);

            if (strpos($msg->body, ':') !== false) {
                // 包含
                $order_pk_id = explode(':', $msg->body)[0]; // 订单号 也是订单表的主键id

//                /** @var StoreOrderServices $storeOrderServices */
//                $storeOrderServices = app()->make(StoreOrderServices::class);
//
//                /** @var BoxOrderServices $boxOrderServices */
//                $boxOrderServices = app()->make(BoxOrderServices::class);

                $storeOrderServices = new StoreOrderServices();

                $orderInfo = Db::name('store_order')->where('id', $order_pk_id)->find();

                if ($orderInfo) {
                    $res = $storeOrderServices->findQuery((string)$orderInfo['order_id']);
//                    $res = $storeOrderServices->findQuery((string)$order_pk_id);

                    if (!empty($res) && !empty($res['data'])) {
//                        $order_status = '';

                        $updateData = [
                            'resp_code' => $res['data']['head']['respCode'] ?? '', // 响应码 成功响应码：000000 [ respCode 这个只是 查询订单的结果是成功还是失败的，失败会返回相respMsg ]
                            'resp_msg' => $res['data']['head']['respMsg'] ?? '', // 响应描述
                            'order_msg' => $res['data']['body']['orderMsg'] ?? '', // 订单状态描述
                            'order_status' => $res['data']['body']['orderStatus'] ?? '', // // orderStatus 是查询成功后出现的，也就是说，在这之前，这笔订单流程已经走完了的。可以查询状态走到哪了
                            'ori_resp_msg' => $res['data']['body']['oriRespMsg'] ?? '', // 原交易应答描述
                            'select_time' => date('Y-m-d H:i:s'),
                            'new_select_time' => time(), // 最新一次的查询时间秒数
                        ];

                        if (!empty($updateData['resp_code'])) {

                            // respCode 这个只是 查询订单的结果是成功还是失败的，失败会返回相respMsg
                            if ($res['data']['head']['respCode'] == '000000') {
                                $updateData['pay_order_code'] = $res['data']['body']['payOrderCode'] ?? ''; // 渠道订单号 如 ：20220622001317100000000000023895

                                // orderStatus 是查询成功后出现的，也就是说，在这之前，这笔订单流程已经走完了的。可以查询状态走到哪了
                                //$updateData['order_status'] = $res['data']['body']['orderStatus'] ?? ''; // 通过杉德订单查询到的状态 00 成功 01 处理中 02 失败 03 已撤销 04 已退货 05 退款处理中

                            }
                        }

                        $order_status = $updateData['order_status'];

                        // 订单状态（0 支付中 1 已付款未到账 2 已付款已到账 3 已退款 4 订单超时 5 支付失败（或者待支付））

//                if ($orderInfo->status == 0) {
//                    if ($order_status == '01') {
//                        $updateData['status'] = 5; // 支付处理中 (可能用户还在支付中输入密码等操作 或者是  杉德在排队)
//                    }
//                }

//            if ($updateData['order_msg'] == '订单待支付') {
//                $updateData['status'] = 5; // 支付处理中 (可能用户还在支付中输入密码等操作 或者是  杉德在排队)
//            }

                        $number = explode(':', $msg->body)[1];

                        // 通过杉德订单查询到的状态 00 成功 01 处理中 02 失败 03 已撤销 04 已退货 05 退款处理中

                        // 杉德告知  订单支付失败
                        if ($orderInfo['status'] == 0 && $order_status == '02' && $number < 3) {
                            $updateData['status'] = 5; // 5 支付失败（或者待支付））
                        }

//                /** @var StoreOrderServices $orderInfo */
//                $orderInfo = $storeOrderServices->getWhere(['id' => $order_pk_id]);

                        // 如果我的订单 已经超时了  然后我查到杉德支付成功了 那么 就 主动退款
                        if ($orderInfo['status'] == 4 && $order_status == '00' && $number >= 3) {
                            $updateData['status'] = 3; // 已退款
                        }

                        $res['select_time'] = date('Y-m-d H:i:s'); // 最新一次的查询时间
                        $select_return = json_encode($res, JSON_UNESCAPED_UNICODE);

                        // 如果是 第一次查询
                        if ($number == 1) {
                            $updateData['select_one_msg'] = $select_return;
                            $updateData['new_select_count'] = 1;
                        }

                        // 如果是 第二次查询
                        if ($number == 2) {
                            $updateData['select_two_msg'] = $select_return;
                            $updateData['new_select_count'] = 2;
                        }

                        // 如果是 第三次查询
                        if ($number == 3) {
                            $updateData['select_three_msg'] = $select_return;
                            $updateData['new_select_count'] = 3;
                        }

                        // 如果是 第四次查询
                        if ($number == 4) {
                            $updateData['select_four_msg'] = $select_return;
                            $updateData['new_select_count'] = 4;
                        }

                        // 如果是 第五次查询
                        if ($number == 5) {
                            $updateData['select_five_msg'] = $select_return;
                            $updateData['new_select_count'] = 5;
                        }

                        // 如果是 第六次查询
                        if ($number == 6) {
                            $updateData['select_six_msg'] = $select_return;
                            $updateData['new_select_count'] = 6;

                            $ttl = (6 + 1) * time() * 1000;
                            if ($orderInfo['status'] == 4 && $order_status == '01') {
                                $storeOrderServices->sendSelectOrderMsg($order_pk_id . ':7', $ttl);
                            }
                        }

                        if ($orderInfo['status'] == 4 && $order_status == '01' && $number > 6) {

                            /*
                             *  针对未收到应答订单，或应答非终态的订单，可通过该接口发起订单查询；
                                交易查询主要规则如下 ：
                                基于单笔订单查询每次间隔如下:5秒、10秒、30秒、60秒、120秒、600秒、3600秒
                                不符合间隔规则的查询请求将会被拦截
                             *  5*1=5,5*2=10,10*3=30,30*4=120,120*5=600,600*6=3600
                             * */
                            $new_select_count = $orderInfo['new_select_count'] + 1; // 最新查询次数 = 上一次 加 1
                            $updateData['last_msg'] = $select_return; // 6次后的最新一次查询结果
                            $updateData['new_select_count'] = $new_select_count; // 最新查询次数

                            $ttl = $new_select_count * $orderInfo['new_select_time'] * 1000;

                            $storeOrderServices->sendSelectOrderMsg($order_pk_id . ':' . $new_select_count, $ttl);
                        }

                        Db::name('store_order')->where('id', $order_pk_id)->update($updateData);

//                        $storeOrderServices->updateWhere(['id' => $order_pk_id], $updateData);

                        if ($order_status == '00' && $number < 3) {
                            // 说明  根据查询 发现 订单已经支付成功了
                            switch ($orderInfo['type']) {
                                // 0 购买藏品成功通知
                                case 0:
                                    $storeOrderServices->selectPayNotify((int)$order_pk_id);
                                    break;
                                // 1 购买盲盒成功通知
                                case 1:
                                    $boxOrderServices = new BoxOrderServices();
                                    $boxOrderServices->selectBoxPayNotify((int)$order_pk_id);
                                    break;
//                                // 2 钱包充值成功通知
//                                case 2:
//                                    $storeOrderServices->selectBalanceNotify((int)$order_pk_id);
//                                    break;
                            }
                        }

                        $refundOrderServices = new RefundOrderServices();

                        // 执行退款
                        // 订单状态（0 支付中 1 已付款未到账   2 已付款已到账 3 已退款 4 订单超时 5 支付失败（或者待支付））
                        if ($orderInfo['status'] == 0 || $orderInfo['status'] == 4 || $orderInfo['status'] == 5) {
                            if ($order_status == '00' && $number >= 3) {
                                // 执行到 5分01秒 查询之后  才得知 订单支付成功 那么 自动去给他退款
                                $refundOrderServices->orderRefund((string)$order_pk_id);
                            }
                        }

                    }

                }
            }

            $msg->ack();
        };
        $channel->basic_qos(null, 1, null);
        $channel->basic_consume($queue_name, '', false, false, false, false, $callback);

        while ($channel->is_open()) {
            $channel->wait();
        }


        return self::SUCCESS;
    }

}
